package com.example.loop.controller;

import com.example.loop.entity.R;
import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.Item;
import io.swagger.annotations.*;
import jdk.nashorn.internal.parser.JSONParser;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author Liaorun
 */
@Slf4j
@RestController
@RequestMapping("/file")
@Api(value = "管理文件的接口")
public class FileController {


    @Resource
    private MinioClient minioClient;

    @Value("${minio.bucketName}")
    private String bucketName;


    @ApiOperation("查询minio中的所有文件")
    @GetMapping("/list")
    public List<Object> list() throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        // 获取bucket列表
        Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());
        Iterator<Result<Item>> iterator = results.iterator();

        ArrayList<Object> objects = new ArrayList<>();

        String format = "{fileName: %s, fileSize: %s}";

        while (iterator.hasNext()) {
            Item item = iterator.next().get();
            String quote = JSONParser.quote(String.format(format, item.objectName(), item.size()));
            objects.add(quote);
        }

        return objects;
    }


    @ApiOperation("上传文件到minio")
    @PostMapping(value = "/upload")
    public R upload(@RequestPart MultipartFile[] files) {
        if (files == null) {
            return R.failed("上传文件不能为空");
        }

        for (MultipartFile file : files) {

            InputStream inputStream = null;
            try {
                inputStream = file.getInputStream();
                minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(file.getOriginalFilename())
                        .stream(inputStream, file.getSize(), -1).contentType(file.getContentType()).build());
            } catch (IOException | ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | InvalidResponseException | NoSuchAlgorithmException | ServerException | XmlParserException e) {
                e.printStackTrace();

                return R.failed("上传失败" + e.getMessage());
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        return R.ok("上传成功");
    }

    @DeleteMapping("/delete/{fileName}")
    public R delete(@PathVariable("fileName") String fileName) {
        try {
            minioClient.removeObject(
                    RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build()
            );
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException | XmlParserException e) {
            e.printStackTrace();

            return R.failed("fail");
        }

        return R.ok("ok");
    }

    @ApiOperation("下载minio的文件")
    @GetMapping(value = "/download/{fileName}")
    public void download(HttpServletResponse response, @PathVariable String fileName) throws ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        InputStream inputStream = null;

        try {
            // 获取对象信息
            StatObjectResponse statObjectResponse = minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(fileName).build());
            response.setContentType(statObjectResponse.contentType());
            response.setHeader("Content-Disposition", "attachment;filename=" +
                    URLEncoder.encode(fileName, "UTF-8"));

            // 文件下载
            inputStream = minioClient.getObject(
                    GetObjectArgs.builder().bucket(bucketName).object(fileName).build());

            IOUtils.copy(inputStream, response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error(e.getMessage());
                }
            }
        }

    }
}
